package com.undsf.cpudb.collect

import com.undsf.cpudb.entities.CpuInfo
import com.undsf.crawler.CachedCrawler
import org.jsoup.Jsoup
import org.jsoup.nodes.TextNode
import org.jsoup.select.Elements

import java.text.SimpleDateFormat
import java.util.regex.Pattern

class CpuBenchmarkCrawler extends CachedCrawler {
    Pattern pattern_comment = Pattern.compile("<!-- Array\\s*\\(\\s*(\\s*\\[\\w+\\]\\s*=>\\s*.*)+\\s\\)\\s*-->")
    Pattern pattern_prop = Pattern.compile("\\[(\\w+)\\] => (.*)")

    CpuBenchmarkCrawler() {
        super()
    }

    def crawlCpuList() {
        def cpuIdList = new ArrayList<Integer>()
        def cpulist_content = getFromCache("http://cpubenchmark.net/cpu_list.php")
        def doc = Jsoup.parse(cpulist_content)
        def table = doc.select("#cputable").first()
        def trs = table.select("tr[id]")
        // println("获取到节点数量：" + trs.size())
        for (def tr : trs) {
            def id = tr.attr("id")
            if (id.startsWith("cpu")) {
                cpuIdList.add(Integer.parseInt(id.substring(3)))
            }
        }
        return cpuIdList
    }

    def crawlCpuInfo(int id) {
        CpuInfo cpuInfo = new CpuInfo()
        cpuInfo.id = id

        def url = "https://www.cpubenchmark.net/cpu.php?id=" + id
        def html = getFromCache(url)

        def matcher = pattern_comment.matcher(html)
        boolean findit = matcher.find()
        // println "是否找到特征注释：" + (findit ? "是" : "否")
        def comment = matcher.group()
        matcher = pattern_prop.matcher(comment)

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd")

        while (matcher.find()) {
            def prop = matcher.group(1)
            def value = matcher.group(2)
            // println(prop + ": " + value)
            switch (prop) {
                case "name":
                    cpuInfo.name = value.trim()
                    break
                case "rating":
                    cpuInfo.mark = Integer.parseInt(value)
                    break
                case "released":
                    cpuInfo.releaseDate = sdf.parse(value)
                    break
                case "price":
                    cpuInfo.price = Double.parseDouble(value)
                    break
                case "threadRating":
                    cpuInfo.threadRating = Double.parseDouble(value)
                    break
            }
        }

        def doc = Jsoup.parse(html)
        def table = doc.select(".desc").first()
        // cpuInfo.name = table.select("span#cpuname").first()
        def strongNodes = new Elements()
        def em = table.select("em").first()
        strongNodes.addAll(em.select("strong"))
        // println("找到加粗节点" + strongNodes.size() + "个")
        for(def node : strongNodes) {
            def textNode = (TextNode)node.nextSibling()
            // println(node.text() + textNode)
            switch (node.text()) {
                case "Socket:":
                    cpuInfo.socket = textNode.text().trim()
                    break
                case "Clockspeed:":
                    cpuInfo.clockSpeedStr = textNode.text().trim()
                    break
                case "Turbo Speed:":
                    cpuInfo.turboSpeedStr = textNode.text().trim()
                    break
                case "No of Cores:":
                    cpuInfo.coresStr = textNode.text().trim()
                    break
                case "Typical TDP:":
                    cpuInfo.typicalTDPStr = textNode.text().trim()
                    break
            }
        }

        return cpuInfo
    }

    def crawl() {
        def cpuIdList = crawlCpuList()
        println("获取到CPU数量：" + cpuIdList.size())

        println("开始抓取数据 ... ")
        int counter = 0
        for (def cpuId : cpuIdList) {
            def cpuInfo = crawlCpuInfo(cpuId)
            counter++
            def progress = (int)(counter * 100 / cpuIdList.size())
            // println("[" + progress + "%] " + cpuInfo)
            println(cpuInfo.toCSV())
        }
    }

    static void main(String[] args) {
        CpuBenchmarkCrawler crawler = new CpuBenchmarkCrawler()
        crawler.crawl()
    }
}
